#include "../include/TcpServer.h"
#include "../include/TcpConnection.h"
#include "../include/ThreadPool.h"
#include <iostream>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <errno.h>
#include <fcntl.h>  // 主要包含 fcntl() 函数、F_GETFL、F_SETFL 的定义
#include <unistd.h> // 包含文件描述符操作相关的函数

TcpServer::TcpServer(int port, ThreadPool *thread_pool)
    : _port(port), _listen_fd(-1), _epoll_fd(-1), _running(false), _thread_pool(thread_pool)
{
    std::cout << "创建TCP服务器，端口: " << _port << std::endl;
}

TcpServer::~TcpServer()
{
    stop();
    // 清除所有连接
    _connections.clear();
    std::cout << "TCP服务器销毁" << std::endl;
}

void TcpServer::setNonBlocking(int fd)
{
    int flags = fcntl(fd, F_GETFL, 0);
    fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}

void TcpServer::addFd(int epoll_fd, int fd, uint32_t events)
{
    epoll_event ev;
    ev.events = events;
    ev.data.fd = fd;

    // 使用水平触发(默认)而不是边缘触发
    // ev.events |= EPOLLET; // 移除边缘触发

    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
    {
        std::cerr << "添加fd到epoll失败: " << strerror(errno) << std::endl;
    }
    else
    {
        std::cout << "✅ 添加fd到epoll: fd=" << fd << std::endl;
    }
}

void TcpServer::removeFd(int epoll_fd, int fd)
{
    if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, nullptr) < 0)
    {
        std::cerr << "从epoll移除fd失败: " << strerror(errno) << std::endl;
    }
    close(fd);
}

void TcpServer::start()
{
    // 创建监听socket
    _listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (_listen_fd < 0)
    {
        throw std::runtime_error("创建socket失败: " + std::string(strerror(errno)));
    }

    // 设置SO_REUSEADDR
    int opt = 1;
    if (setsockopt(_listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
    {
        throw std::runtime_error("设置SO_REUSEADDR失败: " + std::string(strerror(errno)));
    }

    // 绑定地址
    sockaddr_in server_addr{};
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(_port);

    if (bind(_listen_fd, (sockaddr *)&server_addr, sizeof(server_addr)) < 0)
    {
        throw std::runtime_error("绑定端口失败: " + std::string(strerror(errno)));
    }

    // 监听
    if (listen(_listen_fd, 128) < 0)
    {
        throw std::runtime_error("监听失败: " + std::string(strerror(errno)));
    }

    // 创建epoll实例
    _epoll_fd = epoll_create1(0);
    if (_epoll_fd < 0)
    {
        throw std::runtime_error("创建epoll失败: " + std::string(strerror(errno)));
    }

    // 添加监听socket到epoll
    addFd(_epoll_fd, _listen_fd, EPOLLIN | EPOLLET); // 边缘触发

    setNonBlocking(_listen_fd);

    _running = true;
    std::cout << "✅ TCP服务器启动成功，监听端口: " << _port << std::endl;

    // 开始事件循环
    handleEvents();
}

void TcpServer::stop()
{
    if (!_running)
        return;

    _running = false;

    if (_epoll_fd >= 0)
    {
        close(_epoll_fd);
        _epoll_fd = -1;
    }

    if (_listen_fd >= 0)
    {
        close(_listen_fd);
        _listen_fd = -1;
    }

    std::cout << "TCP服务器已停止" << std::endl;
}

void TcpServer::handleAccept()
{
    sockaddr_in client_addr{};
    socklen_t client_len = sizeof(client_addr);

    std::cout << "🔄 处理连接请求..." << std::endl;

    while (true)
    {
        int client_fd = accept(_listen_fd, (sockaddr *)&client_addr, &client_len);
        if (client_fd < 0)
        {
            if (errno == EAGAIN || errno == EWOULDBLOCK)
            {
                break;
            }
            else
            {
                std::cerr << "接受连接失败: " << strerror(errno) << std::endl;
                break;
            }
        }

        std::cout << "✅ 接受新连接: fd=" << client_fd << std::endl;

        // 设置非阻塞
        setNonBlocking(client_fd);

        // 创建TcpConnection并保存到映射中
        auto conn = std::make_shared<TcpConnection>(client_fd);
        _connections[client_fd] = conn; // 重要：保存连接对象

        // 添加到epoll
        addFd(_epoll_fd, client_fd, EPOLLIN | EPOLLRDHUP);

        // 调用连接回调
        if (_connection_callback)
        {
            _connection_callback(conn);
        }

        std::cout << "🔗 新的客户端连接: " << inet_ntoa(client_addr.sin_addr)
                  << ":" << ntohs(client_addr.sin_port) << std::endl;
        std::cout << "📊 当前连接数: " << _connections.size() << std::endl;
    }
}

void TcpServer::handleEvents()
{
    const int MAX_EVENTS = 64;
    epoll_event events[MAX_EVENTS];

    std::cout << "✅ 开始事件循环..." << std::endl;

    while (_running)
    {
        int nfds = epoll_wait(_epoll_fd, events, MAX_EVENTS, 1000);

        if (nfds < 0)
        {
            if (errno == EINTR)
            {
                continue;
            }
            std::cerr << "epoll_wait错误: " << strerror(errno) << std::endl;
            break;
        }

        if (nfds == 0)
        {
            continue;
        }

        std::cout << "📡 处理 " << nfds << " 个事件" << std::endl;

        for (int i = 0; i < nfds; ++i)
        {
            int fd = events[i].data.fd;

            if (fd == _listen_fd)
            {
                std::cout << "🎯 监听socket事件" << std::endl;
                handleAccept();
            }
            else
            {
                std::cout << "🎯 客户端socket事件: fd=" << fd << std::endl;

                if (events[i].events & (EPOLLRDHUP | EPOLLHUP | EPOLLERR))
                {
                    // 连接关闭或错误
                    std::cout << "🔌 连接关闭: fd=" << fd << std::endl;
                    auto it = _connections.find(fd);
                    if (it != _connections.end())
                    {
                        if (_close_callback)
                        {
                            _close_callback(it->second);
                        }
                        _connections.erase(it); // 从映射中移除
                    }
                    removeFd(_epoll_fd, fd);
                }
                else if (events[i].events & EPOLLIN)
                {
                    // 可读事件
                    std::cout << "📨 数据可读: fd=" << fd << std::endl;

                    auto it = _connections.find(fd);
                    if (it != _connections.end())
                    {
                        auto conn = it->second;
                        std::string data = conn->receive();
                        std::cout << "📥 接收到数据: " << data.size() << " 字节" << std::endl;

                        if (!data.empty() && _message_callback)
                        {
                            std::cout << "🎯 调用消息回调..." << std::endl;
                            _message_callback(conn, data);
                        }
                        else if (data.empty())
                        {
                            std::cout << "🔌 连接关闭(空数据): fd=" << fd << std::endl;
                            if (_close_callback)
                            {
                                _close_callback(conn);
                            }
                            _connections.erase(it);
                            removeFd(_epoll_fd, fd);
                        }
                    }
                }
            }
        }
    }
}

void TcpServer::setConnectionCallback(std::function<void(TcpConnectionPtr)> cb)
{
    _connection_callback = cb;
}

void TcpServer::setMessageCallback(std::function<void(TcpConnectionPtr, const std::string &)> cb)
{
    _message_callback = cb;
}

void TcpServer::setCloseCallback(std::function<void(TcpConnectionPtr)> cb)
{
    _close_callback = cb;
}